home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 1 / PC Actual CD 01.iso / share / dos / graficos / plydat14.arj / RINGS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-29  |  7.8 KB  |  214 lines

  1. /*
  2.  * rings.c - Create objects with 6 pentagonal rings which connect the midpoints
  3.  *     of the edges of a dodecahedron.  A pyramid of these objects is formed,
  4.  *     which the viewer looks upon from the point.  A plane is placed behind
  5.  *     the pyramid for shadows.  No object is clipped.  Three light sources.
  6.  *
  7.  * Version:  2.2 (11/17/87)
  8.  * Author:  Eric Haines, 3D/Eye, Inc.
  9.  *
  10.  * SIZE_FACTOR determines the number of objects output.
  11.  *     Each object has 30 cylinders and 30 spheres.
  12.  *     Total objects = SF*SF + (SF-1)*(SF-1) + ... + 1 plus 1 backdrop square.
  13.  *     formula for # of spheres or cylinders = 5*SF*(SF+1)*(2*SF+1)
  14.  *
  15.  *     SIZE_FACTOR      # spheres       # cylinders     # squares
  16.  *          1               30                30             1
  17.  *          2              150               150             1
  18.  *          3              420               420             1
  19.  *
  20.  *          7             4200              4200             1
  21.  */
  22.  
  23. #include <stdio.h>
  24. #include <math.h>
  25. #ifdef MAC
  26. #include <console.h>
  27. #endif
  28.  
  29. #include "def.h"
  30. #include "lib.h"
  31.  
  32. #define SIZE_FACTOR   2
  33.  
  34. /* if spread out is > 1, succeeding layers spread out more */
  35. #define SPREAD_OUT              1
  36.  
  37. /* Create the set of 30 points needed to generate the rings */
  38. static void
  39. create_dodec(double minor_radius, COORD4 vertex[30])
  40. {
  41.     long    num_vertex, num_pentagon ;
  42.     COORD4  temp_vertex ;
  43.     MATRIX  x_matrix, z_matrix ;
  44.     double  scale, x_rotation, z_rotation ;
  45.  
  46.  
  47.     /* scale object to fit in a sphere of radius 1 */
  48.  
  49.     scale = 1.0 / ( 1.0 + minor_radius ) ;
  50.     /*
  51.      * define one pentagon as on the XY plane, with points starting along +X
  52.      * and N fifths of the way around the Z axis.
  53.      */
  54.     for ( num_vertex = 0 ; num_vertex < 5 ; ++num_vertex ) {
  55.         vertex[num_vertex].x = scale * cos( (double)num_vertex * 2.0*PI/5.0 ) ;
  56.         vertex[num_vertex].y = scale * sin( (double)num_vertex * 2.0*PI/5.0 ) ;
  57.         vertex[num_vertex].z = 0.0 ;
  58.         vertex[num_vertex].w = 1.0 ;
  59.     }
  60.  
  61.     /*
  62.      * find the rotation angle (in radians) along the X axis:
  63.      * angle between two adjacent dodecahedron faces.
  64.      */
  65.     x_rotation = 2.0 *
  66.                 acos( cos( (double)(PI/3.0) ) / sin( (double)(PI/5.0) ) ) ;
  67.     lib_create_rotate_matrix( x_matrix, X_AXIS, x_rotation ) ;
  68.  
  69.     /*
  70.      * Find each of the other 5 pentagons:  rotate along the X axis,
  71.      * then rotate on the Z axis.
  72.      */
  73.     for ( num_pentagon = 1 ; num_pentagon < 6 ; ++num_pentagon ) {
  74.         /*
  75.          * find the rotation angle (in radians) along the Z axis:
  76.          * 1/10th plus N fifths of the way around * 2 * PI.
  77.          */
  78.         z_rotation = PI*( 2.0*(double)(num_pentagon-1)+1.0 ) / 5.0 ;
  79.         lib_create_rotate_matrix( z_matrix, Z_AXIS, z_rotation ) ;
  80.  
  81.         for ( num_vertex = 0 ; num_vertex < 5 ; ++num_vertex ) {
  82.  
  83.             lib_transform_coord( &temp_vertex
  84.                                , &vertex[num_vertex]
  85.                                , x_matrix
  86.                                ) ;
  87.  
  88.             lib_transform_coord( &vertex[5*num_pentagon+num_vertex]
  89.                                , &temp_vertex
  90.                                , z_matrix
  91.                                ) ;
  92.         }
  93.     }
  94. }
  95.  
  96. void
  97. main(int argc, char *argv[])
  98. {
  99.     COORD4  base_pt, apex_pt, offset ;
  100.     COORD4  wall[4], dodec[30] ;
  101.     COORD4  from, at, up, dir;
  102.     COORD4  wvec, light ;
  103.     COORD4  back_color, ring_color[6] ;
  104.     long    prev_elem ;
  105.     long    num_elem ;
  106.     long    num_depth, num_objx, num_objz ;
  107.     double  radius ;
  108.     double  spread, y_diff, xz_diff ;
  109.     char *txname, *c[6];
  110.     int cind = 0;
  111.  
  112. #ifdef MAC
  113.    argc = ccommand(&argv);
  114. #endif
  115.  
  116.  
  117.     radius = 0.07412 ;  /* cone and sphere radius */
  118.  
  119.     /* calculate spread of objects */
  120.     spread = 1 / sin( (double)( PI/8.0 ) ) ;
  121.     if ( SPREAD_OUT <= spread ) {
  122.         y_diff = spread / SPREAD_OUT ;
  123.         xz_diff = 1.0 ;
  124.     }
  125.     else {
  126.         y_diff = 1.0 ;
  127.         xz_diff = SPREAD_OUT / spread ;
  128.     }
  129.  
  130.     /* output viewpoint */
  131.     SET_COORD( from, -1.0, -spread, 0.5 ) ;
  132.     SET_COORD( at, from.x, from.y + 1.0, from.z ) ;
  133.     SET_COORD( up, 0.0, 0.0, 1.0 ) ;
  134.     lib_output_viewpoint( &from, &at, &up, 45.0, 1.0, 1.0, 256, 256);
  135.  
  136.     /* output background color - UNC sky blue */
  137.     /* note that the background color should never be seen */
  138.     SET_COORD( back_color, 0.078, 0.361, 0.753 ) ;
  139.     lib_output_background_color( &back_color ) ;
  140.  
  141.     /* output light source */
  142.     SET_COORD( light, 3.0, -spread, 3.0 ) ;
  143.     lib_output_light( &light ) ;
  144.     SET_COORD( light, -4.0, -spread, 1.0 ) ;
  145.     lib_output_light( &light ) ;
  146.     SET_COORD( light, 2.0, -spread, -4.0 ) ;
  147.     lib_output_light( &light ) ;
  148.  
  149.     /* Output bounding slabs oriented along the coordinate axes */
  150.     SET_COORD(dir, 1.0, 0.0, 0.0);
  151.     lib_output_bounding_slab(&dir);
  152.     SET_COORD(dir, 0.0, 1.0, 0.0);
  153.     lib_output_bounding_slab(&dir);
  154.     SET_COORD(dir, 0.0, 0.0, 1.0);
  155.     lib_output_bounding_slab(&dir);
  156.  
  157.     /* output wall polygon - white */
  158.     SET_COORD( back_color, 1.0, 1.0, 1.0 ) ;
  159.     txname = lib_output_color(&back_color, 0.2, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0);
  160.     /* just spans 45 degree view + 1% */
  161.     wvec.y = y_diff * ( SIZE_FACTOR + 1 ) ;
  162.     wvec.x = wvec.z = 1.01 * ( wvec.y - from.y ) * tan( PI / 8.0 ) ;
  163.     SET_COORD( wall[0],  wvec.x+from.x, wvec.y,  wvec.z+from.z ) ;
  164.     SET_COORD( wall[1], -wvec.x+from.x, wvec.y,  wvec.z+from.z ) ;
  165.     SET_COORD( wall[2], -wvec.x+from.x, wvec.y, -wvec.z+from.z ) ;
  166.     SET_COORD( wall[3],  wvec.x+from.x, wvec.y, -wvec.z+from.z ) ;
  167.     lib_output_polygon(4, wall, txname);
  168.  
  169.     /* set up ring colors - RGB and complements */
  170.     SET_COORD(ring_color[0], 1.0, 0.0, 0.0);
  171.     SET_COORD(ring_color[1], 0.0, 1.0, 0.0);
  172.     SET_COORD(ring_color[2], 0.0, 0.0, 1.0);
  173.     SET_COORD(ring_color[3], 0.0, 1.0, 1.0);
  174.     SET_COORD(ring_color[4], 1.0, 0.0, 1.0);
  175.     SET_COORD(ring_color[5], 1.0, 1.0, 0.0);
  176.     c[0] = lib_output_color(&ring_color[0], 0.2, 0.5, 0.5, 10.0, 0.0, 0.0, 0.0);
  177.     c[1] = lib_output_color(&ring_color[1], 0.2, 0.5, 0.5, 10.0, 0.0, 0.0, 0.0);
  178.     c[2] = lib_output_color(&ring_color[2], 0.2, 0.5, 0.5, 10.0, 0.0, 0.0, 0.0);
  179.     c[3] = lib_output_color(&ring_color[3], 0.2, 0.5, 0.5, 10.0, 0.0, 0.0, 0.0);
  180.     c[4] = lib_output_color(&ring_color[4], 0.2, 0.5, 0.5, 10.0, 0.0, 0.0, 0.0);
  181.     c[5] = lib_output_color(&ring_color[5], 0.2, 0.5, 0.5, 10.0, 0.0, 0.0, 0.0);
  182.  
  183.     create_dodec( radius, dodec ) ;
  184.     /* radius of osculating cylinders and spheres (no derivation given) */
  185.     base_pt.w = apex_pt.w = radius ;
  186.  
  187.     for ( num_depth = 0 ; num_depth < SIZE_FACTOR ; ++num_depth ) {
  188.         offset.y = y_diff * (double)(num_depth+1) ;
  189.         for ( num_objz = 0 ; num_objz <= num_depth ; ++num_objz ) {
  190.             offset.z = xz_diff * (double)(2*num_objz - num_depth) ;
  191.             for ( num_objx = 0 ; num_objx <= num_depth ; ++num_objx ) {
  192.                 offset.x = xz_diff * (double)(2*num_objx - num_depth) ;
  193.                 for ( num_elem = 0 ; num_elem < 30 ; ++num_elem ) {
  194.                     COPY_COORD( base_pt, dodec[num_elem] ) ;
  195.                     ADD2_COORD( base_pt, offset ) ;
  196.                     if ( num_elem%5 == 0 ) {
  197.                         prev_elem = num_elem + 4 ;
  198.                         /* new ring beginning - output color */
  199.                         cind = num_elem/5;
  200.                        }
  201.                     else {
  202.                         prev_elem = num_elem - 1 ;
  203.                        }
  204.                     COPY_COORD( apex_pt, dodec[prev_elem] ) ;
  205.                     ADD2_COORD( apex_pt, offset ) ;
  206.  
  207.                     lib_output_cylcone( &base_pt, &apex_pt, c[cind]);
  208.                     lib_output_sphere( &base_pt, c[cind]);
  209.                 }
  210.             }
  211.         }
  212.     }
  213. }
  214.